using System;
using QFramework.Framework.ResKit.Data;
using UnityEngine;

namespace QFramework.Framework.ResKit.Res
{
    /// <summary>
    ///     AssetBundle 资源对象
    /// </summary>
    public class AssetBundleRes : Res
    {
        private ResLoader _resLoader = new();

        public AssetBundleRes(string assetName)
        {
            Path = ResKitUtil.FullPathForAssetBundle(assetName);

            Name = assetName;

            State = ResState.Waiting;
        }

        public AssetBundle AssetBundle
        {
            get => Asset as AssetBundle;
            set => Asset = value;
        }

        public override bool LoadSync()
        {
            State = ResState.Loading;

            var dependencyBundleNames = ResData.Instance.GetDirectDependencies(Name);

            foreach (var dependencyBundleName in dependencyBundleNames)
                _resLoader.LoadSync<AssetBundle>(dependencyBundleName);

            if (!ResMgr.IsSimulationModeLogic) AssetBundle = AssetBundle.LoadFromFile(Path);

            State = ResState.Loaded;

            return AssetBundle;
        }

        private void LoadDependencyBundlesAsync(Action onAllLoaded)
        {
            var dependencyBundleNames = ResData.Instance.GetDirectDependencies(Name);

            if (dependencyBundleNames.Length == 0)
                onAllLoaded();

            var loadedCount = 0;

            foreach (var dependencyBundleName in dependencyBundleNames)
                _resLoader.LoadAsync<AssetBundle>(dependencyBundleName,
                    dependencyBundle =>
                    {
                        loadedCount++;

                        if (loadedCount == dependencyBundleNames.Length)
                            onAllLoaded();
                    });
        }

        public override void LoadAsync()
        {
            State = ResState.Loading;

            LoadDependencyBundlesAsync(() =>
            {
                if (ResMgr.IsSimulationModeLogic)
                {
                    State = ResState.Loaded;
                }
                else
                {
                    var resRequest = AssetBundle.LoadFromFileAsync(Path);

                    resRequest.completed += operation =>
                    {
                        AssetBundle = resRequest.assetBundle;

                        State = ResState.Loaded;
                    };
                }
            });
        }

        protected override void OnReleaseRes()
        {
            if (AssetBundle != null)
            {
                AssetBundle.Unload(true);
                AssetBundle = null;

                _resLoader.ReleaseAll();
                _resLoader = null;
            }

            ResMgr.Instance.SharedLoadedReses.Remove(this);
        }
    }
}